package com.beadwallet.alarm.web;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.beadwallet.alarm.entity.alarmInfo.AlarmInfo;
import com.beadwallet.alarm.service.alarm.AlarmInfoService;
import com.beadwallet.alarm.util.CheckResultUtil;
import com.beadwallet.alarm.util.IPUtil;
import com.beadwallet.alarm.util.PropertiesUtil;
import com.beadwallet.alarm.util.WeChatUtil;
import com.beadwallet.alarm.entity.wechat.AccessToken;
import com.beadwallet.alarm.service.email.BrSendMailI;
import com.beadwallet.alarm.service.wechat.SendMessageService;
import com.beadwallet.alarm.config.WeChatParames;
import com.beadwallet.common.aspect.WebLog;
import com.beadwallet.common.controller.BaseController;
import com.beadwallet.common.enums.CodeEnum;
import com.beadwallet.common.utils.AlarmUtil;
import com.beadwallet.common.utils.RedisUtils;
import com.beadwallet.common.utils.StringUtils;
import io.swagger.annotations.Api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Set;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author jackcooper
 * @since 2017-11-30
 */
@RestController
@RequestMapping("alarm")
@Api(value = "alarm", description = "警报系统", tags = "alarm")
public class AlarmController extends BaseController {
    /**
     * 微信发送消息接口
     *
     * @param content  发送的消息
     * @param touser   成员ID
     * @param toparty  部门ID
     * @param to       邮件收件人
     * @param subject  邮件主题
     * @return {"code":"000000","message":"成功"} 或者 {"code":"100001","message":"失败"}
     */
    private static Logger log = LoggerFactory.getLogger(AlarmController.class);

    @Autowired
    private SendMessageService sendMessageService;

    @Autowired
    private AlarmInfoService iAlarmInfoService;

    @Autowired
    private AlarmUtil alarmUtil;

    @Autowired
    private RedisUtils redisUtils;

    private static int times;

    /**
     *
     * @param request
     * @return
     */
    @WebLog(description = "getIp")
    @PostMapping("/getIp")
    private String getIp(HttpServletRequest request) {
        return IPUtil.getIpAddr(request);
    }

    /**
     * @param mails  收件人
     * @param appType  项目ID
     * @param content  内容
     * @param subject  主题
     * @return
     */
    /*@WebLog(description = "sendMessage")
    @PostMapping("/sendMessage")
    public String sendMessage(String mails,String appType, String content, String subject){
        StringBuilder builder = new StringBuilder();
        builder.append("[");
        builder.append(getIp(request));
        builder.append("] : ");
        subject = builder + subject;
        //创建sendMail对象
        BrSendMailI mailInstance = BrSendMailI.getMailInstance();
        //创建一个JsonObject对象
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("senderAddr", PropertiesUtil.getStringValue("senderAddr"));
        jsonObject.put("senderPwd", PropertiesUtil.getStringValue("senderPwd"));
        log.warn("mails:{}",mails);
        //设置发送类型
        String wechatAndMailSend = "3";
        String mailSend = "2";
        if(StringUtils.isEmpty(mails)) {
            //根据项目Id查询数据
            Wrapper<AlarmInfo> wrapper = new EntityWrapper<>();
            log.warn("appType:{}",appType);
            wrapper.eq("project_id", appType);
            if(StringUtils.isNotEmpty(appType)) {
                AlarmInfo alarmInfo = iAlarmInfoService.selectOne(wrapper);
                String[] strings = alarmInfo.getMailRecipient().split(",");
                for (String string : strings) {
                    log.warn("string:{}",string);
                }
                //获取AccessToken
                AccessToken accessToken = WeChatUtil.getAccessToken(WeChatParames.CORP_ID, WeChatParames.CORPSE_CRET);
                //根据参数判断发送类型
                log.warn("content:{}",content);
                //可能为微信或邮件或微信邮件
                if (StringUtils.isNotEmpty(content)) {
                    //可能为邮件或微信邮件
                    log.warn("subject:{}",subject);
                    if (StringUtils.isNotEmpty(subject)) {
                        if (alarmInfo.getSendType().equals(wechatAndMailSend)) {
                            try {
                                String wechatRecipients = alarmInfo.getWechatRecipient().replaceAll(",", "|");
                                //调用微信推送消息方法
                                JSONObject json = sendMessageService.sendMessage(accessToken.getToken(), "subject: "+ subject + "       content: " + content, wechatRecipients, null);
                                //对返回的结果进行校验  000000 100001
                                String code = CheckResultUtil.checkWeChatResult(json);
                                if(CodeEnum.SUCC.getCode().equals(code)) {
                                    log.warn("微信发送成功");
                                }
                            } catch (Exception e) {
                                log.error("Wechat sendError :{}" + e);
                                alarmUtil.sendAlarm(appType,"微信发送失败",e);
                            }
                            try {
                                //调用发送邮件方法
                                String emailMsg = mailInstance.sendToMails(jsonObject.toJSONString(), strings, subject, content);
                                if (CodeEnum.SUCC.getCode().equals(emailMsg)) {
                                    log.warn("邮件发送成功");
                                    return respJson(CodeEnum.SUCC, "微信邮件发送成功");
                                }
                            }catch (Exception e){
                                alarmUtil.sendAlarm(appType, "微信邮件发送失败", "警报系统:" + "微信邮件发送失败");
                                return respJson(CodeEnum.FAILURE, "微信邮件发送失败");
                            }
                            //邮件
                        } else if (alarmInfo.getSendType().equals(mailSend)) {
                            try {
                                //调用发送邮件方法
                                String emailMsg = mailInstance.sendToMails(jsonObject.toJSONString(), strings, subject, content);
                                if (CodeEnum.SUCC.getCode().equals(emailMsg)) {
                                    log.warn("邮件发送成功");
                                    return respJson(CodeEnum.SUCC, "邮件发送成功");
                                }
                            }catch (Exception e){
                                alarmUtil.sendAlarm(appType, "邮件发送失败", "警报系统:" + "邮件发送失败");
                                return respJson(CodeEnum.FAILURE, "邮件发送失败");
                            }
                            //微信
                        } else {
                            String wechatRecipients = alarmInfo.getWechatRecipient().replaceAll(",", "|");
                            log.warn("wechatRecipients:{}",wechatRecipients);
                            //调用微信推送消息方法
                            JSONObject json = sendMessageService.sendMessage(accessToken.getToken(), "subject: "+ subject + "       content: " + content, wechatRecipients, null);
                            //对返回的结果进行校验  000000 100001
                            String code = CheckResultUtil.checkWeChatResult(json);
                            if(CodeEnum.SUCC.getCode().equals(code)){
                                log.warn("微信发送成功");
                                return respJson(CodeEnum.SUCC, json);
                            }else{
                                alarmUtil.sendAlarm(appType,"微信发送失败",json.toString());
                                return respJson(CodeEnum.FAILURE, json);
                            }
                        }
                    }
                } else {
                    alarmUtil.sendAlarm(appType,"内容为空","警报系统:" + "内容为空");
                    return respJson(CodeEnum.FAILURE, "内容为空");
                }
            } else {
                alarmUtil.sendAlarm(appType,"appType错误","警报系统:" + "appType错误");
                return respJson(CodeEnum.FAILURE, "请输入有效的appType");
            }
        }else{
            try {
                String[] mail = mails.split(",");
                //调用发送邮件方法
                String emailMsg = mailInstance.sendToMails(jsonObject.toJSONString(), mail, subject, content);
                if (CodeEnum.SUCC.getCode().equals(emailMsg)) {
                    log.warn("邮件发送成功");
                    return respJson(CodeEnum.SUCC, "邮件发送成功");
                }
            }catch (Exception e){
                alarmUtil.sendAlarm(appType, "邮件发送失败", "mails 邮件发送失败");
                return respJson(CodeEnum.FAILURE, "邮件发送失败");
            }
        }
        return null;
    }*/




    @WebLog(description = "sendMessage")
    @PostMapping("/sendMessage")
    public String sendMessage(String mails,String appType, String content, String subject){
        StringBuilder builder = new StringBuilder();
        builder.append("[");
        builder.append(getIp(request));
        builder.append("] : ");
        subject = builder + subject;
        //创建sendMail对象
        BrSendMailI mailInstance = BrSendMailI.getMailInstance();
        //创建一个JsonObject对象
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("senderAddr", PropertiesUtil.getStringValue("senderAddr"));
        jsonObject.put("senderPwd", PropertiesUtil.getStringValue("senderPwd"));
        log.warn("mails:{}",mails);
        //邮件相关
        String subjectHash = String.valueOf(subject.hashCode());
        long currentTimeMillis = System.currentTimeMillis();
        String mills = String.valueOf(currentTimeMillis);

        //设置发送类型
        String wechatAndMailSend = "3";
        String mailSend = "2";
        if(StringUtils.isEmpty(mails)) {
            //根据项目Id查询数据
            Wrapper<AlarmInfo> wrapper = new EntityWrapper<>();
            log.warn("appType:{}",appType);
            wrapper.eq("project_id", appType);
            if(StringUtils.isNotEmpty(appType)) {
                AlarmInfo alarmInfo = iAlarmInfoService.selectOne(wrapper);
                String[] strings = alarmInfo.getMailRecipient().split(",");
                for (String string : strings) {
                    log.warn("string:{}",string);
                }
                //获取AccessToken
                AccessToken accessToken = WeChatUtil.getAccessToken(WeChatParames.CORP_ID, WeChatParames.CORPSE_CRET);
                //根据参数判断发送类型
                log.warn("content:{}",content);
                //可能为微信或邮件或微信邮件
                if (StringUtils.isNotEmpty(content)) {
                    //可能为邮件或微信邮件
                    log.warn("subject:{}",subject);
                    if (StringUtils.isNotEmpty(subject)) {
                        if (alarmInfo.getSendType().equals(wechatAndMailSend)) {
                            try {
                                String wechatRecipients = alarmInfo.getWechatRecipient().replaceAll(",", "|");
                                //调用微信推送消息方法
                                JSONObject json = sendMessageService.sendMessage(accessToken.getToken(), "subject: "+ subject + "       content: " + content, wechatRecipients, null);
                                //对返回的结果进行校验  000000 100001
                                String code = CheckResultUtil.checkWeChatResult(json);
                                if(CodeEnum.SUCC.getCode().equals(code)) {
                                    log.warn("微信发送成功");
                                }
                            } catch (Exception e) {
                                log.error("Wechat sendError :{}" + e);
                                alarmUtil.sendAlarm(appType,"微信发送失败",e);
                            }
                            try {
                                //调用发送邮件方法
                                String emailMsg = mailInstance.sendToMails(jsonObject.toJSONString(), strings, subject, content);
                                Boolean alarmTime = redisUtils.exists("alarm:alarm_time");
                                if(alarmTime){
                                    String currentMills = redisUtils.get("alarm:currentMills");
                                    Set<String> alarm_time = redisUtils.zrangeByScore("alarm:alarm_time", Double.valueOf(currentMills), Double.valueOf(currentMills));
                                    log.warn("mills:{}",Double.valueOf(mills));
                                    for (String hash : alarm_time) {
                                        if (CodeEnum.SUCC.getCode().equals(emailMsg) && subjectHash.equals(hash)) {
                                            ifTimesExits(subjectHash);
                                            sendLevel(strings, subject, content);
                                            redisUtils.zadd("alarm:alarm_time", Double.valueOf(mills), subjectHash);
                                            redisUtils.set("alarm:currentMills",mills);
                                            return respJson(CodeEnum.SUCC, "微信邮件发送成功");
                                        }else{
                                            redisUtils.zadd("alarm:alarm_times", 1, subjectHash);
                                            redisUtils.set("alarm:currentMills",mills);
                                            redisUtils.zadd("alarm:alarm_time", Double.valueOf(mills), subjectHash);
                                            log.warn("subjectHash:{}",subjectHash);
                                            redisUtils.set("alarm:times","1");
                                            sendLevel(strings, subject, content);
                                            return respJson(CodeEnum.SUCC, "微信邮件发送成功");
                                        }
                                    }
                                }else {
                                    redisUtils.zadd("alarm:alarm_time", Double.valueOf(mills), subjectHash);
                                    redisUtils.set("alarm:currentMills",mills);
                                    if (CodeEnum.SUCC.getCode().equals(emailMsg) && subjectHash.equals(subjectHash)) {
                                        ifTimesExits(subjectHash);
                                        sendLevel(strings, subject, content);
                                        return respJson(CodeEnum.SUCC, "微信邮件发送成功");
                                    }else{
                                        ifTimesExits(subjectHash);
                                        sendLevel(strings, subject, content);
                                        return respJson(CodeEnum.SUCC, "微信邮件发送成功");
                                    }
                                }
                            }catch (Exception e){
                                alarmUtil.sendAlarm(appType, "微信邮件发送失败", e);
                                return respJson(CodeEnum.FAILURE, "微信邮件发送失败");
                            }
                            //邮件
                        } else if (alarmInfo.getSendType().equals(mailSend)) {
                            try {
                                //调用发送邮件方法
                                String emailMsg = mailInstance.sendToMails(jsonObject.toJSONString(), strings, subject, content);
                                String sendSuccess = alarm(mills, emailMsg, subjectHash, strings, subject, content);
                                return sendSuccess;
                            }catch (Exception e){
                                alarmUtil.sendAlarm(appType, "邮件发送失败", e);
                                return respJson(CodeEnum.FAILURE, "邮件发送失败");
                            }
                            //微信
                        } else {
                            String wechatRecipients = alarmInfo.getWechatRecipient().replaceAll(",", "|");
                            log.warn("wechatRecipients:{}",wechatRecipients);
                            //调用微信推送消息方法
                            JSONObject json = sendMessageService.sendMessage(accessToken.getToken(), "subject: "+ subject + "       content: " + content, wechatRecipients, null);
                            //对返回的结果进行校验  000000 100001
                            String code = CheckResultUtil.checkWeChatResult(json);
                            if(CodeEnum.SUCC.getCode().equals(code)){
                                log.warn("微信发送成功");
                                return respJson(CodeEnum.SUCC, json);
                            }else{
                                alarmUtil.sendAlarm(appType,"微信发送失败",json.toString());
                                return respJson(CodeEnum.FAILURE, json);
                            }
                        }
                    }
                } else {
                    alarmUtil.sendAlarm(appType,"内容为空","警报系统:" + "内容为空");
                    return respJson(CodeEnum.FAILURE, "内容为空");
                }
            } else {
                alarmUtil.sendAlarm(appType,"appType错误","警报系统:" + "appType错误");
                return respJson(CodeEnum.FAILURE, "请输入有效的appType");
            }
        }else{
            String[] mail = mails.split(",");
            try {
                //调用发送邮件方法
                String emailMsg = mailInstance.sendToMails(jsonObject.toJSONString(), mail, subject, content);
                if (CodeEnum.SUCC.getCode().equals(emailMsg)) {
                    log.warn("邮件发送成功");
                    return respJson(CodeEnum.SUCC, "mails 邮件发送成功");
                }
            }catch (Exception e){
                alarmUtil.sendAlarm(appType, "邮件发送失败", e);
                return respJson(CodeEnum.FAILURE, "邮件发送失败");
            }
        }
        return respJson(CodeEnum.FAILURE,"发送失败");
    }

    /**
     * 判断警报的发送等级
     * @param strings  以逗号分隔后的邮箱
     * @param subject  主题
     * @param content  内容
    */
    private void sendLevel(String[] strings,String subject,String content){
        //创建sendMail对象
        BrSendMailI mailInstance = BrSendMailI.getMailInstance();
        //创建一个JsonObject对象
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("senderAddr", PropertiesUtil.getStringValue("senderAddr"));
        jsonObject.put("senderPwd", PropertiesUtil.getStringValue("senderPwd"));
        switch (times){
            case 20:
                mailInstance.sendToMails(jsonObject.toJSONString(), strings, subject, PropertiesUtil.getStringValue("firstLevelContent") + content);
                log.warn("一级警报发送成功");
                break;
            case 100:
                mailInstance.sendToMails(jsonObject.toJSONString(), strings, subject, PropertiesUtil.getStringValue("secondLevelContent") + content);
                log.warn("二级警报发送成功");
                break;
            case 1000:
                mailInstance.sendToMails(jsonObject.toJSONString(), strings, subject, PropertiesUtil.getStringValue("thirdLevelContent") + content);
                log.warn("三级警报发送成功");
                break;
            case 3000:
                mailInstance.sendToMails(jsonObject.toJSONString(), strings, subject, PropertiesUtil.getStringValue("fourthLevelContent") + content);
                log.warn("四级警报发送成功");
                break;
            case 10000:
                mailInstance.sendToMails(jsonObject.toJSONString(), strings, subject, PropertiesUtil.getStringValue("fiveLevelContent") + content);
                log.warn("五级警报发送成功");
                break;
            default:
                log.warn("邮件发送成功");
                break;
        }
    }

    /**
     *
     * @param mills         当前时间
     * @param emailMsg      发送邮件的返回码
     * @param subjectHash   主题的hash值
     * @param strings       收件人
     * @param subject       邮件主题
     * @param content       主题内容
     * @return
     */
    private String alarm(String mills,String emailMsg,String subjectHash,String[] strings,String subject,String content){
        Boolean alarmTime = redisUtils.exists("alarm_time");
        if(alarmTime){
            String currentMills = redisUtils.get("alarm:currentMills");
            Set<String> alarm_time = redisUtils.zrangeByScore("alarm:alarm_time", Double.valueOf(currentMills), Double.valueOf(currentMills));
            log.warn("mills:{}",Double.valueOf(mills));
            for (String hash : alarm_time) {
                if (CodeEnum.SUCC.getCode().equals(emailMsg) && subjectHash.equals(hash)) {
                    ifTimesExits(subjectHash);
                    sendLevel(strings, subject, content);
                    redisUtils.zadd("alarm:alarm_time", Double.valueOf(mills), subjectHash);
                    redisUtils.set("alarm:currentMills",mills);
                    return respJson(CodeEnum.SUCC, "邮件发送成功");
                }else{
                    redisUtils.zadd("alarm:alarm_times", 1, subjectHash);
                    redisUtils.set("alarm:currentMills",mills);
                    redisUtils.zadd("alarm:alarm_time", Double.valueOf(mills), subjectHash);
                    log.warn("subjectHash:{}",subjectHash);
                    redisUtils.set("alarm:times","1");
                    sendLevel(strings, subject, content);
                    return respJson(CodeEnum.SUCC, "邮件发送成功");
                }
            }
        }else {
            redisUtils.zadd("alarm:alarm_time", Double.valueOf(mills), subjectHash);
            redisUtils.set("alarm:currentMills",mills);
            if (CodeEnum.SUCC.getCode().equals(emailMsg) && subjectHash.equals(subjectHash)) {
                ifTimesExits(subjectHash);
                sendLevel(strings, subject, content);
                return respJson(CodeEnum.SUCC, "邮件发送成功");
            }else{
                ifTimesExits(subjectHash);
                sendLevel(strings, subject, content);
                return respJson(CodeEnum.SUCC, "邮件发送成功");
            }
        }
        return respJson(CodeEnum.SUCC, "邮件发送成功");
    }

    private void ifTimesExits(String subjectHash){
        Boolean ifTimesExits = redisUtils.exists("alarm:times");
        if(ifTimesExits){
            times = Integer.valueOf(redisUtils.get("alarm:times"));
            Set<String> alarmTime = redisUtils.zrangeByScore("alarm:alarm_times", Double.valueOf(times), Double.valueOf(times));
            for (String hash : alarmTime) {
                if(subjectHash.equals(hash)){
                    times++;
                }else {
                    times = 1;
                }
            }
            redisUtils.zadd("alarm:alarm_times", times, subjectHash);
            redisUtils.set("alarm:times",String.valueOf(times));
        }else {
            redisUtils.zadd("alarm:alarm_times", 1, subjectHash);
            redisUtils.set("alarm:times","1");
        }
    }
}